package cate.game.role.res.guild.handler;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDGuild;
import cate.common.table.d.GDMail;
import cate.common.util.GameResult;
import cate.game.GameBody;
import cate.game.event.guild.GuildCreatedEvent;
import cate.game.mail.po.MailBuilder;
import cate.game.res.MixRes;
import cate.game.role.Role;
import cate.game.role.base.RoleBase;
import cate.game.role.mail.Mail;
import cate.game.role.res.guild.po.GuildApplyDetailPO;
import cate.game.role.res.guild.po.GuildPO;
import cate.game.role.res.guild.po.member.GuildMemberDetailPO;
import cate.game.role.res.guild.po.my.MyGuildApplyDetailPO;
import cate.game.util.api.ChatApi;
import easy.java.dev.note.NoteClass;
import easy.java.practice.errorcode.EcResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@NoteClass(value = "公会基础操作")
public class GuildManageAction {
    /**
     * 创建公会条件检测
     */
    public EcResult checkCreateGuild(Role role, String guildName, int pattern, int background, GuildCreatedEvent createdEvent) {
        EcResult r = new EcResult<>();
        GameResult<Void> rFunc = role.getGame().table.common.funcEnable.isEnable(role.getBase().level
                ,role.getBase().vip
                , 0
                , 0
                , GDFunc.GuildFunc.GUILD
                , 0);
        if(!rFunc.ok()){
            role.getGame().notice.message(role, rFunc.message);
            return r.fail();
        }
        // 判断惩罚时间
        long pastSecond = (System.currentTimeMillis() - role.getRes().guild.withdrawalTime) / 1000;

        long punishSecond = getPunishSecond(role.getGame());

        if (pastSecond < punishSecond) {
            long dif = punishSecond - pastSecond;
            long hour = dif / 3600;
            int min = (int) (dif - hour * 3600) / 60;
            List<Object> params = new ArrayList<>();
            params.add(hour);
            params.add(min);
            role.getGame().notice.message(role, 310453, "{}小时{}分后才能创建新的公会", params);
            return r.fail(hour + "小时" + min + "分后才能创建新的公会");
        }
        // 判断vip等级是否满足
        if (role.getBase().vip < GDGuild.basic.VIP_LEVEL_REQUIRED) {
            List<Object> params = new ArrayList<>();
            params.add(GDGuild.basic.VIP_LEVEL_REQUIRED);
            role.getGame().notice.message(role, 310454, "VIP{}级后可以创建公会", params);
            return r.fail("VIP" + GDGuild.basic.VIP_LEVEL_REQUIRED + "级后可以创建公会");
        }
        // 公会名称检测
        r = this.checkGuildName(role, guildName, null);
        if (!r.ok()) {
            return r.fail(r.message);
        }
        if (!role.getGame().table.guild.bannerBack.containCheck(background)) {
            role.getGame().notice.message(role, 310455, "当前设置旗帜背景不存在");
            return r.fail("当前设置旗帜背景不存在");
        }
        if (!role.getGame().table.guild.bannerPattern.containCheck(pattern)) {
            role.getGame().notice.message(role, 310456, "当前设置旗帜图标不存在");
            return r.fail("当前设置旗帜图标不存在");
        }

        // 判断创建公会费用够不够
        MixRes cost = new MixRes(GDGuild.basic.CREATE_COST);
        r = cost.consumeCheck(role, null);
        if (!r.ok()) {
            role.getGame().notice.message(role, 310457, "费用不足");
            return r.fail("费用不足");
        }
        // 省市检测
        role.getHistory().action.hadAGuild();
        createdEvent.setConsume(cost);
        return r.success();
    }

    /**
     * 公会宣言检测
     */
    public EcResult checkDeclaration(Role role, String declaration) {
        EcResult r = new EcResult();
//        if (StringUtils.isEmpty(declaration)) {
//            role.getGame().notice.message(role, 310458, "宣言不能为空");
//            return r.fail();
//        }
        if (declaration.length() > GDGuild.basic.DECLARATION_LENGTH_MAX) {
            role.getGame().notice.message(role, 310459, "字数超过上限");
            return r.fail();
        }
        if (!role.getGame().tools.sensitiveWords.legal(declaration)) {
            role.getGame().notice.message(role, 310460, "您输入的文字中存在敏感字符");
            return r.fail();
        }
        EcResult rChatApi = ChatApi.checkGuildDeclaration(role, declaration);
        if (!rChatApi.ok()) {
            role.getGame().notice.message(role, rChatApi);
            return rChatApi;
        }
        return r.success();
    }

    /**
     * 检查公会名称
     */
    public EcResult checkGuildName(Role role, String name, String guildId) {
        EcResult r = new EcResult();
        if (StringUtils.isBlank(name)) {
            role.getGame().notice.message(role, 310461, "公会名称不能为空");
            return r.fail("公会名称不能为空");
        }
        if (name.length() < GDGuild.basic.NAME_LENGTH_MIN
                || name.length() > GDGuild.basic.NAME_LENGTH_MAX) {
            role.getGame().notice.message(role, 310462, "公会名字必须在2-14个字符之间");
            return r.fail("公会名字必须在2-14个字符之间");
        }
        if (!role.getGame().tools.sensitiveWords.legal(name)) {
            role.getGame().notice.message(role, 310460, "您输入的文字中存在敏感字符");
            return r.fail("您输入的文字中存在敏感字符");
        }
        GameResult<String> rChatApi = ChatApi.checkGuildName(role, name);
        if (!rChatApi.ok()) {
            role.getGame().notice.message(role, rChatApi.message);
            return rChatApi;
        }
        for (GuildPO guild : role.getGame().res.guild.getGuildList()) {
            if (StringUtils.equals(name, guild.basic.guildName)) {
                if (StringUtils.equals(guild.uid, guildId)) {
                    role.getGame().notice.message(role, 310464, "公会名称未修改");
                    return r.fail("公会名称未修改");
                } else {
                    role.getGame().notice.message(role, 310465, "公会名称已被占用");
                    return r.fail("公会名称已被占用");
                }
            }
        }
        return r.success();
    }


    /**
     * 根据开服天数获取离开公会的惩罚时间
     *
     * @param game game
     * @return ms
     */
    public long getPunishSecond(GameBody game) {
        if (game.status.getOpenDay() == 1) {
            return GDGuild.basic.FIRST_DAY_PUNISH_SECOND;
        } else {
            return GDGuild.basic.PUNISH_SECOND;
        }
    }

    /**
     * 解散公会
     */
    public GameResult<Void> disbandGuild(Role role) {
        GameResult<Void> r = new GameResult<>();
        byte pos = role.getRes().guild.getPos();
        if (pos != GDGuild.position.PRESIDENT) {
            role.getGame().notice.message(role, 310447, "仅有会长可以解散公会");
        }
        GuildPO guild = role.getRes().guild.getGuild();
        // 给所有成员发邮件
        List<Object> params = new ArrayList<>();
        params.add(role.getBase().name);
        params.add(guild.basic.guildName);
        Mail mail;
        // 您所在公会会长xx解散了公会！
        mail = new MailBuilder()
                .setContentId(GDMail.Tid.GUILD_DISBAND)
                .setParamList(params)
                .build();
        for (GuildMemberDetailPO detail : guild.member.list) {
            role.getGame().mail.send(detail.it.uid, mail.copy());
            // 移除所有在线公会成员的公会信息，并通知
            role.getGame().role.activeForOnlineRole(detail.it.uid, e -> {
                e.getRes().guild.clear();
                e.getRes().guild.noticeUpdate();
            });
        }
        return r.success();
    }

    /**
     * 申请加入公会
     */
    public void applyJoinGuild(Role role, String guildId) {
        RoleBase base = role.getBase();
        GameResult<Void> rFunc = role.getGame().table.common.funcEnable.isEnable(base.level, base.vip, 0, 0, GDFunc.GuildFunc.GUILD, 0);
        if (!rFunc.ok()) {
            role.getGame().notice.message(role, rFunc.message);
            return;
        }

        // 判断惩罚时间
        if (role.getRes().guild.withdrawalTime > 0) {
            long pastSecond = (System.currentTimeMillis() - role.getRes().guild.withdrawalTime) / 1000;
            long punishSecond = getPunishSecond(role.getGame());
            if (pastSecond < punishSecond) {
                long dif = punishSecond - pastSecond;
                long hour = dif / 3600;
                int min = (int) (dif - hour * 3600) / 60;
                List<Object> params = new ArrayList<>();
                params.add(hour);
                params.add(min);
                role.getGame().notice.message(role, 310448, "%d小时%d分后才能申请加入新的公会", params);
                return;
            }
        }
        // 入会条件检测
        GameResult<Void> r = role.getRes().guild.apply.checkApply(guildId);
        if (!r.ok()) {
            return;
        }
        GuildPO guild = role.getGame().res.guild.getGuild(guildId);
        if (guild.basic.authentication) {
            // 在公会里记录申请信息
            r = guild.apply.addApply(role, new GuildApplyDetailPO(role), guildId);
            if (!r.ok()) {
                return;
            }
            // 在玩家身上记录申请的公会,并通知
            role.getRes().guild.apply.addApply(new MyGuildApplyDetailPO(guildId));
            role.getGame().notice.message(role, 310449, "已发送申请");
        } else {
            // 这里处理人和申请人都是自己
            guild.apply.handleJoinExe(role, role, true);
        }
    }

    public EcResult autoDisbandGuild(GuildPO guild) {
        String guildIdHex = guild.uid;
        // 验证能否解散
        EcResult r = disbandGuild(guild);
        if (!r.ok()) {
            return r;
        }
        log.info(String.format("因连续%d天建设资金不足,公会自动解散", GDGuild.build.BUILD_DISBAND_UNFIX_DAY));
        // 执行删除逻辑
        guild.game.res.guild.removeGuild(guild.game, guildIdHex);
        return r.success();
    }

    public EcResult disbandGuild(GuildPO guild) {
        EcResult r = new EcResult();
        // 给所有成员发邮件
        List<Object> params = new ArrayList<>();
        params.add(guild.basic.guildName);
        Mail mail;
        // 您所在公会因连续GDGuild.build.BUILD_DEFAULT_UNFIX_DAY天未成功提供建设资金，公会解散！
        mail = new MailBuilder()
                .setContentId(GDMail.Tid.GUILD_AUTO_DISBAND)
                .setParamList(params)
                .build();
        for (GuildMemberDetailPO detailPO : guild.member.list) {
            guild.game.mail.send(detailPO.it.uid, mail.copy());
        }
        // 移除所有在线公会成员的公会信息，并通知
        for (Role member : guild.member.getOnlineRole()) {
            member.getRes().guild.clear();
            member.getRes().guild.noticeUpdate();
            member.getBase().updatePower();
        }
        return r.success();
    }

}
